import java.io.File;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;

import codeg.Codeg;
import gui.SWTCodegGUI;


public class ImageCodegGUI implements SWTCodegGUI {
    private ImageCodeg codeg;
    private Image image = null;
    private Canvas canvas = null;
    private Label label = null;
    private Display display;
    private int size = 128;
    
    public void populate(final Composite content)
    {
        display = content.getDisplay();
        content.setLayout(new GridLayout(2, false));
        
        canvas = new Canvas(content, SWT.TRANSPARENT | SWT.BORDER);
        canvas.addListener(SWT.Paint, new Listener() {
            public void handleEvent(Event e) {
                GC gc = e.gc;
                gc.drawImage(image, 0, 0);
            }
        });
        
        canvas.setSize(size, size);
        GridData imgGridData = new GridData(SWT.CENTER, SWT.CENTER, false, false);
        imgGridData.minimumWidth = size;
        imgGridData.minimumHeight = size;
        imgGridData.widthHint = size;
        imgGridData.heightHint = size;
        
        imgGridData.verticalSpan = 2;
        canvas.setLayoutData(imgGridData);
        
        label = new Label(content, SWT.LEFT);
        if (codeg.getPath() != null)
            label.setText("File: " + codeg.getPath().getAbsolutePath());
        else
            label.setText("File: No file selected");
        label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        
        Button button = new Button(content, SWT.PUSH);
        button.setText("Select image");
        button.setLayoutData(new GridData(SWT.RIGHT, SWT.BOTTOM, true, false));
        
        button.addMouseListener(new MouseListener()
        {
            public void mouseUp(MouseEvent e)
            {
                edit(canvas);
            }
            
            public void mouseDown(MouseEvent e)
            {
            };
            
            public void mouseDoubleClick(MouseEvent e)
            {
            };
        });
        
        if (codeg.getPath() == null)
            show_message("No file to display");
        else if (!codeg.getPath().canRead())
            show_message("File not found");
        else
            refreshImage();
    }
    
    private void show_message(String msg) {
        image = new Image(display, size, size);
        GC gc = new GC(image);
        gc.fillRectangle(0, 0, size, size);
        gc.drawText(msg, 4, 4);
        gc.dispose();

        canvas.setSize(size, size);
        ((GridData) canvas.getLayoutData()).minimumWidth = size;
        ((GridData) canvas.getLayoutData()).minimumHeight = size;
        ((GridData) canvas.getLayoutData()).widthHint = size;
        ((GridData) canvas.getLayoutData()).heightHint = size;
        canvas.getParent().pack(true);
        
        canvas.redraw();
    }
    private void refreshImage()
    {
        try {
            image = new Image(canvas.getDisplay(), codeg.getPath().getAbsolutePath());
        } catch (SWTException e) {
            show_message("Invalid format");
            return;
        }
        
        Rectangle newSize = calcSize(image, size);
        int newWidth = newSize.width;
        int newHeight = newSize.height;
        
        Image scaled = new Image(Display.getDefault(), newWidth, newHeight);
        GC gc = new GC(scaled);
        gc.setAntialias(SWT.ON);
        gc.setInterpolation(SWT.HIGH);
        gc.drawImage(image, 0, 0, image.getBounds().width, image.getBounds().height, 0, 0, newWidth, newHeight);
        gc.dispose();
        image.dispose();
        
        canvas.setSize(newWidth, newHeight);
        ((GridData) canvas.getLayoutData()).minimumWidth = newWidth;
        ((GridData) canvas.getLayoutData()).minimumHeight = newHeight;
        ((GridData) canvas.getLayoutData()).widthHint = newWidth;
        ((GridData) canvas.getLayoutData()).heightHint = newHeight;
        canvas.getParent().pack(true);
        
        image = scaled;
        canvas.redraw();
        label.setText("File: " + codeg.getPath().getAbsolutePath());
    }
    
    
    private void edit(Canvas canvas)
    {
        FileDialog dialog = new FileDialog(canvas.getShell(), SWT.OPEN);
        dialog.setText("Select an image file");
        String fname = dialog.open();
        
        if (fname != null)
        {
            setPath(new File(fname));
            refreshImage();
            codeg.changed();
        }
    }
    
    private Rectangle calcSize(Image img, int max)
    {
        Rectangle rect = img.getBounds();
        
        int currWidth = rect.width;
        int currHeight = rect.height;
        double ratio;
        
        if (currHeight >= currWidth && currHeight > max)
        {
            ratio = currHeight / max;
            currHeight = max;
            currWidth = (int) (currWidth / ratio);
        }
        else if (currWidth >= currHeight && currWidth > max)
        {
            ratio = currWidth / max;
            currWidth = max;
            currHeight = (int) (currHeight / ratio);            
        }
        return new Rectangle(0, 0, currWidth, currHeight);
    }

    public void setPath(File filePath) {
        codeg.setPath(filePath);
        if (label != null && codeg.getPath() != null)
            label.setText("File: " + codeg.getPath().getAbsolutePath());       
    }

    public Codeg getCodeg() {
        return codeg;
    }

    public void setCodeg(Codeg codeg) {
        this.codeg = (ImageCodeg) codeg;
    }
}
